package com.atguigu.meinian.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.comm.ResponseMessage;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.aliyun.oss.model.PutObjectResult;
import com.atguigu.meinian.constant.MessageConstant;
import com.atguigu.meinian.constant.RedisConstant;
import com.atguigu.meinian.constant.RedisMessageConstant;
import com.atguigu.meinian.vo.R;
import redis.clients.jedis.JedisPool;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author zbystart
 * @create 2021-06-22 9:59
 */
public class MeiNianUtils {

    /**
     * 专门负责上传文件到OSS服务器的工具方法
     * @param sign true，上传的是讲师图片，false，上传的是课程分类表格文件
     * @param endpoint            OSS参数
     * @param accessKeyId        OSS参数
     * @param accessKeySecret    OSS参数
     * @param inputStream        要上传的文件的输入流
     * @param bucketName        OSS参数
     * @param bucketDomain        OSS参数
     * @param originalName        要上传的文件的原始文件名
     * @param jedisPool
     * @return	包含上传结果以及上传的文件在OSS上的访问路径
     */
    public static R uploadFileToOss(
            String endpoint,
            String accessKeyId,
            String accessKeySecret,
            InputStream inputStream,
            String bucketName,
            String bucketDomain,
            String originalName,
//            boolean type,
//            String paperFileName
            JedisPool jedisPool) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        String folderName = null;
        String fileMainName = null;
        String extensionName = null;
        // 生成上传文件的目录
        folderName = new SimpleDateFormat("yyyyMMdd").format(new Date());
        // 生成上传文件在OSS服务器上保存时的文件名
        // 原始文件名：beautfulgirl.jpg
        // 生成文件名：wer234234efwer235346457dfswet346235.jpg
        // 使用UUID生成文件主体名称
        fileMainName = UUID.randomUUID().toString().replace("-", "");
        // 从原始文件名中获取文件扩展名
        extensionName = originalName.substring(originalName.lastIndexOf("."));
        // 使用目录、文件主体名称、文件扩展名称拼接得到对象名称
        String objectName = folderName + "/" + fileMainName + extensionName;


        try {
            // 调用OSS客户端对象的方法上传文件并获取响应结果数据
            PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, inputStream);

            // 从响应结果中获取具体响应消息
            ResponseMessage responseMessage = putObjectResult.getResponse();

            // 根据响应状态码判断请求是否成功
            if(responseMessage == null) {

                // 拼接访问刚刚上传的文件的路径
                String ossFileAccessPath = bucketDomain + "/" + objectName;
                // 上传成功后把上传的图片名保存到redis中
                saveSetmealImageNameToRedis(RedisConstant.ALIYUNIMAGENAMES,objectName,jedisPool);
                // 当前方法返回成功
                return R.ok(MessageConstant.PIC_UPLOAD_SUCCESS,ossFileAccessPath);
            } else {
                // 获取响应状态码
                int statusCode = responseMessage.getStatusCode();

                // 如果请求没有成功，获取错误消息
                String errorMessage = responseMessage.getErrorResponseAsString();

                // 当前方法返回失败
                return R.error(MessageConstant.PIC_UPLOAD_FAIL);
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 当前方法返回失败
            return R.error(MessageConstant.PIC_UPLOAD_FAIL);
        } finally {

            if(ossClient != null) {
                // 关闭OSSClient。
                ossClient.shutdown();
            }
        }
    }

    public static void deleteImages(String endpoint,String accessKeyId,String accessKeySecret,String bucketName,List<String> keys) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        // 删除文件。
        // 填写需要删除的多个文件完整路径。文件完整路径中不能包含Bucket名称。
        DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(keys));
        List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 获取前一天的日期
     * @return
     */
    public static String getTheDayBefore() {
        Calendar ca = Calendar.getInstance();//得到一个Calendar的实例
        ca.setTime(new Date()); //设置时间为当前时间
        ca.add(Calendar.DATE, -1); //天数减1
        return new SimpleDateFormat("yyyyMMdd").format(ca.getTime());
    }

    public static void saveSetmealImageNameToRedis(String key,String imageName,JedisPool jedisPool) {
        jedisPool.getResource().sadd(key,imageName);
    }

    public static void sendCode(String telephone,Integer length,JedisPool jedisPool,String redisKey,int second) throws Exception {
        Integer code = ValidateCodeUtils.generateValidateCode(length);
        SMSUtils.sendShortMessage(telephone,code.toString());
        jedisPool.getResource().setex(telephone + ":" + redisKey,second,code.toString());
    }

    public static Map<String, String> checkCode(String telephone,String code, JedisPool jedisPool, String redisKey) {
        // 从redis中获取验证码
        String codeFromDb = jedisPool.getResource().get(telephone + ":" + redisKey);
        HashMap<String, String> message = new HashMap<>();

        message.put(MessageConstant.CODE_VERIFY_RESULT_KEY,MessageConstant.CODE_VERIFY_FAIL);

        if (codeFromDb == null) {
            // 验证码不存在，或已过期
            message.put(MessageConstant.CODE_VERIFY_MESSAGE_Key,"验证码已过期请重新发送验证码!");
        } else if(!codeFromDb.equals(code)){
            message.put(MessageConstant.CODE_VERIFY_MESSAGE_Key,"验证码错误");
        } else {
            // 正确的
            message.put(MessageConstant.CODE_VERIFY_RESULT_KEY,MessageConstant.CODE_VERIFY_SUCCESS);
        }
        return message;

    }
}
